// MyImageView without drag & click operation

package scm.chyeung23.mtr;

import java.util.ArrayList;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PointF;
import android.util.AttributeSet;
import android.util.FloatMath;
import android.view.MotionEvent;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

public class MyImageView extends ImageView {
	// Variables for touch
	private final int NONE = 0;
	private final int DRAG = 1;
	private final int ZOOM = 2;
	private int mode = NONE;

	// Station defined by me
	private Station myStation;
	ArrayList<Station> myStations = new ArrayList<Station>();
	private int FromStationIndex, ToStationIndex;
	// private Station[] myStations = new Station[10];

	// for drawing stations
	private Paint rectPaint = new Paint();
	private float[] localPoints = new float[2];
	private float[] tempPoints = new float[2];
	private int radius4Stations = 20;


	// for drag & zoom
	Matrix M_new = new Matrix();
	Matrix M = new Matrix();

	PointF p1 = new PointF();

	private PointF pivot;
	private float dist_old;

	public MyImageView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);

		getStationsDetails();
	}

	public MyImageView(Context context, AttributeSet attrs) {
		super(context, attrs);

		getStationsDetails();
	}

	public MyImageView(Context context) {
		super(context);

		getStationsDetails();
	}

	private void getStationsDetails() {

		myStation = new Station("TST");
		myStation.setGolPos(new PointF(73f, 40f));
		myStations.add(myStation);

		myStation = new Station("TW");
		myStation.setGolPos(new PointF(119f, 40f));
		myStations.add(myStation);
		// myStations.add(myStation);

	}

	/** Determine the space between the first two fingers */
	private float spacing(MotionEvent event) {
		float x = event.getX(0) - event.getX(1);
		float y = event.getY(0) - event.getY(1);
		return FloatMath.sqrt(x * x + y * y);
	}

	/** Calculate the mid point of the first two fingers */
	private PointF midPoint(MotionEvent event) {
		return new PointF((event.getX(0) + event.getX(1)) * 0.5f, (event
				.getY(0) + event.getY(1)) * 0.5f);
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		switch (event.getAction() & MotionEvent.ACTION_MASK) {
		case MotionEvent.ACTION_DOWN:

			mode = DRAG; // start to drag

			p1.set(event.getX(), event.getY());
			M.set(this.getImageMatrix());
			break;
		case MotionEvent.ACTION_POINTER_DOWN: // for pinching
			mode = ZOOM;

			dist_old = spacing(event);
			pivot = midPoint(event);
			M.set(this.getImageMatrix());
			break;
		case MotionEvent.ACTION_MOVE:
			if (mode == DRAG) {
				M_new.set(M);
				// p2 = (e.getX(), e.getY())
				M_new.postTranslate(event.getX() - p1.x, event.getY() - p1.y);

				this.setImageMatrix(M_new);
			} else if (mode == ZOOM) {
				float scale = spacing(event) / dist_old;
				M_new.set(M);
				M_new.postScale(scale, scale, pivot.x, pivot.y);

				this.setImageMatrix(M_new);
			}
			break;
		case MotionEvent.ACTION_POINTER_UP:
		case MotionEvent.ACTION_UP:
			mode = NONE;

			// simulate onClick event
			if (event.getAction() == MotionEvent.ACTION_UP) {

				// we check if positions for touch down/up are close enough,
				// since in practice,
				// it is almost impossible to make finger down & up happen at
				// same position

				// if (dist_squared < 100)
				// {
				onClickEvent(event); // to be defined
				// }
			}

			break;
		}

		return true;
	}

	private void onClickEvent(MotionEvent event) {

		// convert position in device coordinate to image coordinate
		PointF Lpt = DPtoLP(new PointF(event.getX(), event.getY()));
		PointF tStationPos;
		Toast.makeText(this.getContext(), "MouseX:" + Lpt.x + "\nMouseY:"+Lpt.y, Toast.LENGTH_SHORT).show();
		
		for (int i = 0; i < myStations.size(); i++) {

			tStationPos = myStations.get(i).getGolPos(); 
			
			/*float dist_squared = (Lpt.x - myStation.getGolPos().x)
					* (Lpt.x - myStation.getGolPos().x)
					+ (Lpt.y - myStation.getGolPos().y)
					* (Lpt.y - myStation.getGolPos().y);
			*/
			float dist_squared = (Lpt.x - tStationPos.x)*(Lpt.x - tStationPos.x)
									+ (Lpt.y - tStationPos.y)*(Lpt.y - tStationPos.y);
			// if (rect.contains(Lpt.x, Lpt.y))
			if (dist_squared < radius4Stations * radius4Stations) {
				showDislog(myStations.get(i),i);
				// reset matrix, since it is a click event.
				// no dragging/zooming is needed
				this.setImageMatrix(M);
			}

		}

	}

	private void showDislog(final Station station,final int index) {

		final CharSequence[] items = { "From " + station.getName(), "To " + station.getName()};
		AlertDialog.Builder builder = new AlertDialog.Builder(this.getContext());
		//builder.setTitle("Pick a color");
		builder.setItems(items, new DialogInterface.OnClickListener() 
		{
			public void onClick(DialogInterface dialog, int item) 
			{
				//Toast.makeText(MyImageView.this.getContext(), items[item],Toast.LENGTH_SHORT).show();
				if(item==0)
				{
					FromStationIndex = index;
				}
				else
				{
					ToStationIndex = index;
				}
				onDialogClick(station);
			}
		});
		AlertDialog alert = builder.create();
		alert.show();
	}

	protected void onDialogClick(Station station) {
		// TODO Auto-generated method stub
		//Toast.makeText(MyImageView.this.getContext(), "onDialogClick: " + station.getName(),Toast.LENGTH_SHORT).show();
		TextView textView = (TextView)findViewById(R.id.system_map_from);
		
		//Toast.makeText(MyImageView.this.getContext(), textView.set,Toast.LENGTH_SHORT).show();
		if(textView!=null)
		{
			textView.setText(station.getName());
			Toast.makeText(MyImageView.this.getContext(), textView.getText(),Toast.LENGTH_SHORT).show();
		}
		else
		{
			Toast.makeText(MyImageView.this.getContext(), "textView is null",Toast.LENGTH_SHORT).show();
		}
		
	}

	// convert device coordinates to logical(image) coordinates
	public PointF DPtoLP(PointF pt) {
		Matrix matrix = this.getImageMatrix();
		Matrix inverse = new Matrix();

		if (matrix.invert(inverse)) { // if matrix inverse exists
			float[] pts = new float[2];
			pts[0] = pt.x;
			pts[1] = pt.y;
			inverse.mapPoints(pts);

			return new PointF(pts[0], pts[1]);
		}

		return pt; // in case the inverse of the matrix doesn't exist
	}

	@Override
	protected void onDraw(Canvas canvas) {
		// draw the associated image (default behavior)
		super.onDraw(canvas);

		// set painting style
		rectPaint.setColor(Color.RED);
		rectPaint.setAlpha(100);

		// draw stations

		// localPoints[0] = 0f;
		// localPoints[1] = 0f;
		for (int i = 0; i < myStations.size(); i++) {

			// tempPoints[0] = myStation.getGolPos().x;
			// tempPoints[1]= myStation.getGolPos().y;
			tempPoints[0] = myStations.get(i).getGolPos().x;
			tempPoints[1] = myStations.get(i).getGolPos().y;
			this.getImageMatrix().mapPoints(localPoints, tempPoints);
			canvas.drawCircle(localPoints[0], localPoints[1], radius4Stations,
					rectPaint);
		}

	}

	public void setFromStationIndex(int fromStationIndex) {
		FromStationIndex = fromStationIndex;
	}

	public int getFromStationIndex() {
		return FromStationIndex;
	}

	public void setToStationIndex(int toStationIndex) {
		ToStationIndex = toStationIndex;
	}

	public int getToStationIndex() {
		return ToStationIndex;
	}
	public Station getFromStation()
	{
		return myStations.get(FromStationIndex);
	}

	public Station getToStation()
	{
		return myStations.get(ToStationIndex);
	}
	public boolean addStation(Station _station)
	{
		if(_station==null)
			return false;
		else
			return myStations.add(_station);
	}
	public ArrayList<Station> getMyStations() {
		return myStations;
	}
	public int getRadius4Stations() {
		return radius4Stations;
	}

	public void setRadius4Stations(int radius4Stations) {
		this.radius4Stations = radius4Stations;
	}


}
